#ifndef __SNAKE_H__
#define __SNAKE_H__

#include <list>
#include "point.h"
#include "bmp.h"
#include "game_map.h"

// 方向枚举
enum Dir
{
    NONE = 0,
    UP = 1,
    DOWN = 2,
    LEFT = 3,
    RIGHT = 4
};

class Snake
{

    Snake(int *mp) : mp(mp), body("./res/snack_body.bmp"), head_up("./res/snack_head_up.bmp"),
                     head_down("./res/snack_head_down.bmp"), head_left("./res/snack_head_left.bmp"),
                     head_right("./res/snack_head_right.bmp"), tail_up("./res/snack_tail_up.bmp"),
                     tail_down("./res/snack_tail_down.bmp"), tail_left("./res/snack_tail_left.bmp"),
                     tail_right("./res/snack_tail_right.bmp"), direction(RIGHT), isConfused(false)
    {
        init(1, 0);
    }

public:
    ~Snake();

    // 初始化蛇头的位置
    void init(int x = 1, int y = 0);

    void show();
    void move(GameMap *map, int &score, int &speed, bool &is_game_over, int max_speed, int min_speed, bool &is_create_ai_snake);
    Point calculateNewHead();                                                                                                                                  // 计算新蛇头位置
    bool isCollision(const Point &newHead, GameMap *map);                                                                                                      // 碰撞检测
    void handleMovement(const Point &newHead, GameMap *map, int &score, int &speed, bool &isGameOver, int max_speed, int min_speed, bool &is_create_ai_snake); // 处理移动
    bool handleFood(GridState foodType, GameMap *map, int &score, int &speed, bool &isGameOver, int max_speed, int min_speed, bool &is_create_ai_snake);       // 处理食物效果
    void handleBomb(GameMap *map, bool &isGameOver);                                                                                                           // 处理炸弹
    void removeTail(GameMap *map);                                                                                                                             // 移除蛇尾
    void setDirection(int newDirection);

    int getDirection() { return direction; } // 获取当前移动方向
    Point getHeadPosition();                 // 获取蛇头位置

    // 创建和删除实例
    static Snake *instance(int *mp);
    static void delInstance();

private:
    std::list<Point> m_snakeBody;
    static Snake *m_instance; /* 单例实例对象空间指针 */
    int *mp;                  /* 映射数组 */
    BMP body;                 /* 蛇身图片 */
    BMP head_up;              /* 向上蛇头图片*/
    BMP head_down;            /* 向下蛇头图片 */
    BMP head_left;            /* 向左蛇头图片 */
    BMP head_right;           /* 向右蛇头图片 */
    BMP tail_up;              /* 向上蛇尾图片 */
    BMP tail_down;            /* 向下蛇尾图片 */
    BMP tail_left;            /* 向左蛇尾图片 */
    BMP tail_right;           /* 向右蛇尾图片 */
    int direction;            /* 当前移动方向 */
    bool isConfused;          /* 是否混乱 */
    // int flag_time = 0;        // 混乱解除时间
};

#endif